/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.badlogicgames.superjumper;

import java.util.List;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;

public class WorldRenderer {
	static final float FRUSTUM_WIDTH = Settings.FRUSTUM_WIDTH;
	static final float FRUSTUM_HEIGHT = Settings.FRUSTUM_HEIGHT;
	World world;
	ParallaxCamera cam;
	SpriteBatch batch;
	TextureRegion background;
	float barImageBarFullSize = 5;

	Vector2 healthBarBackgroundLocation;

	Vector2 staminaBarBackgroundLocation;

	public WorldRenderer(SpriteBatch batch, World world) {
		this.world = world;
		this.cam = new ParallaxCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
		
		this.cam.position.set( FRUSTUM_WIDTH / 2, 
				FRUSTUM_HEIGHT / 2, 
				0); // camera position
		
		this.batch = batch;
	}

	public void render() {
		// move the camera based on position of pigeon
		if (world.bob.position.y > cam.position.y + 4) {
			cam.position.y = world.bob.position.y - 4;
		}
		
		if (world.bob.position.y < cam.position.y - 4) {
			cam.position.y = world.bob.position.y + 4;
		}
		if (world.bob.position.x > cam.position.x + 2) {
			cam.position.x = world.bob.position.x - 2;
		}
		if (world.bob.position.x < cam.position.x - 7) {
			cam.position.x = world.bob.position.x + 7;
		}
		
		

		cam.update();
		batch.setProjectionMatrix(cam.combined);
		renderBackground();
		renderFloor();
		renderObjects();
		Gdx.app.log("BOB X", this.world.bob.position.x+"");
		Gdx.app.log("BOB Y", this.world.bob.position.y+"");
	}

	public void renderBackground () {
		// sky background layer, no parallax, centered around origin
		//batch.enableBlending();     //for the backmost layer disable blending for efficiency.
		//batch.setProjectionMatrix(cam.calculateParallaxMatrix(0.01f, 1f));
		batch.begin();
		int backgroundWidth = Assets.layers[0].getRegionWidth()/32;   //divide by 32 to get meter out of pixels. 1m = 32pixels.
		int backgroundHeight = Assets.layers[0].getRegionHeight()/32;
		batch.draw(Assets.layers[0],
				cam.position.x - (cam.viewportWidth/2), 0,
				backgroundWidth, backgroundHeight);  // the background image
		
		batch.end();
		
		
		batch.enableBlending();
		// mountain midground layer, 0.5 parallax (move at half speed on x, half speed on y)
		batch.setProjectionMatrix(cam.calculateParallaxMatrix(0.5f, 1f));
		batch.begin();
		backgroundWidth = Assets.layers[1].getRegionWidth()/32;
		backgroundHeight = Assets.layers[1].getRegionHeight()/32;
		int numberOfBackground = (int)Settings.WORLD_WIDTH/backgroundWidth + 1;
		// the second layer of background
		for (int i = 0; i < numberOfBackground; i++) {
			//texture,x,y,originx,originy,width,height,scalex,scaley,rotation
			int x = backgroundWidth * i;
			batch.draw(Assets.layers[1],
					x, 0,
					backgroundWidth, backgroundHeight);  // the mid background image  
		}
		batch.end();

	}


	public void renderObjects() {
		batch.enableBlending();
		batch.begin();
		renderBars();
		renderTurrets();
		renderPlatforms();
		renderItems();
		renderSquirrels();
		renderCastle();
		renderBob();
		batch.end();
	}
	
	public void renderFloor(){
			batch.enableBlending();
			//ground foreground layer, 1.0 parallax (move at full speed)
			batch.setProjectionMatrix(cam.calculateParallaxMatrix(1f, 1f));
			batch.begin();
			List<Floor> floors = world.floors;
			for (int i = 0; i < floors.size(); i++) {
				// the final layer of background
				batch.draw(Assets.layers[2],
						floors.get(i).position.x , floors.get(i).position.y,
						Floor.FLOOR_WIDTH, Floor.FLOOR_HEIGHT);  // the floor where pigeon should walks  
			}
			batch.end();
	}
	
	private void renderCastle() {
		Castle castle = world.castle;
		batch.draw(Assets.castle, castle.position.x - 1, castle.position.y - 1,
				2, 2);
	}

	private void renderBars() {
		final float HEALTH_BAR_X = 1f;
		final float HEALTH_BAR_Y = 9f;
		final float STAMINA_BAR_X = 9f;
		final float STAMINA_BAR_Y = 9f;
		healthBarBackgroundLocation = new Vector2(cam.position.x - FRUSTUM_WIDTH/2 + HEALTH_BAR_X, 
													cam.position.y-(FRUSTUM_HEIGHT/2) + HEALTH_BAR_Y);
		
		staminaBarBackgroundLocation = new Vector2((cam.position.x - FRUSTUM_WIDTH / 2 + STAMINA_BAR_X), 
													(cam.position.y-(FRUSTUM_HEIGHT / 2) + STAMINA_BAR_Y));
		
		batch.draw(Assets.barBackground, 
				this.healthBarBackgroundLocation.x,this.healthBarBackgroundLocation.y, 
				barImageBarFullSize, 0.51f);
	
		
		
		batch.draw(Assets.barBackground,
				this.staminaBarBackgroundLocation.x, this.staminaBarBackgroundLocation.y,
				barImageBarFullSize, 0.51f);
		
		float healthPercent = Pigeon.health / Pigeon.MAX_HEALTH;
		float staminaPercent = Pigeon.stamina / Pigeon.MAX_STAMINA;
		Gdx.app.log("healthPercent", healthPercent + " ");
		Gdx.app.log("staminaPercent", staminaPercent + " ");
		batch.draw(Assets.healthBarUnit, 
				this.healthBarBackgroundLocation.x,	this.healthBarBackgroundLocation.y,
				(barImageBarFullSize * healthPercent), 0.50f);

		batch.draw(Assets.staminaBarUnit, 
				this.staminaBarBackgroundLocation.x, this.staminaBarBackgroundLocation.y,
				(barImageBarFullSize * staminaPercent), 0.50f);
	}

	private void renderBob() {
		TextureRegion keyFrame;
		switch (world.bob.state) {
		case Pigeon.BOB_STATE_FALL:
			keyFrame = Assets.bobFall.getKeyFrame(world.bob.stateTime,
					Animation.ANIMATION_LOOPING);
			break;
		case Pigeon.BOB_STATE_NORMAL:
			keyFrame = Assets.bobJump.getKeyFrame(world.bob.stateTime,
					Animation.ANIMATION_LOOPING);
			break;
		case Pigeon.BOB_STATE_DIED:
		case Pigeon.BOB_STATE_HIT:
		default:
			keyFrame = Assets.bobHit;
		}

		float side = world.bob.velocity.y < 0 ? -1 : 1;
		Sprite s = new Sprite(keyFrame);
		batch.draw(keyFrame, world.bob.position.x - 0.5f,
				world.bob.position.y - 0.5f, Pigeon.BOB_WIDTH / 2,
				Pigeon.BOB_HEIGHT / 2, 1, 1, 1, 1, 0);

	}

	private void renderPlatforms() {
		int len = world.platforms.size();
		for (int i = 0; i < len; i++) {
			Platform platform = world.platforms.get(i);
			TextureRegion keyFrame = Assets.platform;
			if (platform.state == Platform.PLATFORM_STATE_PULVERIZING) {
				keyFrame = Assets.brakingPlatform.getKeyFrame(
						platform.stateTime, Animation.ANIMATION_NONLOOPING);
			}

			batch.draw(keyFrame, platform.position.x - 1,
					platform.position.y - 0.25f, 2, 0.5f);
		}
	}

	private void renderItems() {
		int len = world.springs.size();
		for (int i = 0; i < len; i++) {
			Spring spring = world.springs.get(i);
			batch.draw(Assets.spring, spring.position.x - 0.5f,
					spring.position.y - 0.5f, 1, 1);
		}

		len = world.coins.size();
		for (int i = 0; i < len; i++) {
			Coin coin = world.coins.get(i);
			TextureRegion keyFrame = Assets.coinAnim.getKeyFrame(
					coin.stateTime, Animation.ANIMATION_LOOPING);
			batch.draw(keyFrame, coin.position.x - 0.5f,
					coin.position.y - 0.5f, 1, 1);
		}
	}

	/**
	 * Renders Items like Health, Shield etc based on ItemType.
	 * */

	private void renderSquirrels() {
		int len = world.squirrels.size();
		for (int i = 0; i < len; i++) {
			Squirrel squirrel = world.squirrels.get(i);
			TextureRegion keyFrame = Assets.squirrelFly.getKeyFrame(
					squirrel.stateTime, Animation.ANIMATION_LOOPING);
			float side = squirrel.velocity.x < 0 ? -1 : 1;
			if (side < 0)
				batch.draw(keyFrame, squirrel.position.x + 0.5f,
						squirrel.position.y - 0.5f, side * 1, 1);
			else
				batch.draw(keyFrame, squirrel.position.x - 0.5f,
						squirrel.position.y - 0.5f, side * 1, 1);
		}
	}

	

	private void renderTurrets() {
		int len = world.turrets.size();
		for (int i = 0; i < len; i++) {
			Turret t = world.turrets.get(i);
			batch.draw(Assets.turretNozzle, t.position.x, t.position.y,
					Turret.ORIGIN_X, Turret.ORIGIN_Y, Turret.WIDTH,
					Turret.HEIGHT, 1, 1, t.rotation, t.clockwise);
			
			batch.draw(Assets.turretBase, t.position.x-.6f ,
					t.position.y-.35f , Turret.WIDTH, Turret.HEIGHT);

			renderBullets(t);
		}

	}

	private void renderBullets(Turret t) {
		int numberOfBullets = t.bullets.size();
		for (int i = 0; i < numberOfBullets; i++) {
			Bullet b = t.bullets.get(i);
			TextureRegion keyFrame = Assets.bulletAnim.getKeyFrame(b.stateTime,
					Animation.ANIMATION_LOOPING);
			batch.draw(keyFrame, b.position.x, b.position.y,
					Bullet.BULLET_WIDTH, Bullet.BULLET_HEIGHT);
		}
	}
}
